Initialize new repo
[clinton/website/site/unknownlamer.org.git] / Metaobject Protocols.html
diff --git a/Metaobject Protocols.html b/Metaobject Protocols.html
new file mode 100644 (file)
index 0000000..42d923b
--- /dev/null
@@ -0,0 +1,817 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Metaobject Protocols</title>
+    <meta name="generator" content="muse.el" />
+    <meta http-equiv="Content-Type"
+          content="text/html; charset=utf-8" />
+<link rel="stylesheet" href="default.css" media="screen" />
+  </head>
+  <body>
+    <h1>Metaobject Protocols</h1>
+   <div class="contents">
+<dl>
+<dt>
+<a href="#sec1">Background</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec2">Object Protocols</a>
+</dt>
+<dt>
+<a href="#sec3">CLOS Way of OO</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec4">Classes for scratch data and types</a>
+</dt>
+<dt>
+<a href="#sec5">Generics with methods that implement protocols</a>
+</dt>
+</dl>
+</dd>
+</dl>
+</dd>
+<dt>
+<a href="#sec6">Limitations of Default Language Behavior</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec7">Slot Storage</a>
+</dt>
+<dt>
+<a href="#sec8">Design Patterns</a>
+</dt>
+</dl>
+</dd>
+<dt>
+<a href="#sec9">Metasoftware</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec10">Runtime Generated Classes</a>
+</dt>
+<dt>
+<a href="#sec11">Object Inspection</a>
+</dt>
+</dl>
+</dd>
+<dt>
+<a href="#sec12">Metaobject Protocols</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec13">Limited/Generalized Internals of the Implementation</a>
+</dt>
+<dt>
+<a href="#sec14">Classes of MOPs</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec15">Reflective</a>
+</dt>
+<dt>
+<a href="#sec16">Intercessory</a>
+</dt>
+</dl>
+</dd>
+<dt>
+<a href="#sec17">Violation of Encapsulation?</a>
+</dt>
+</dl>
+</dd>
+<dt>
+<a href="#sec18">MOP Design Principles</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec19">Layered Protocol</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec20">Top level <strong>must</strong> call lower level functions</a>
+</dt>
+<dt>
+<a href="#sec21">Lower level methods are easier to customize</a>
+</dt>
+</dl>
+</dd>
+<dt>
+<a href="#sec22">Functional Where Possible</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec23">Memoization</a>
+</dt>
+<dt>
+<a href="#sec24">Cleaner Code</a>
+</dt>
+</dl>
+</dd>
+<dt>
+<a href="#sec25">Procedural Only Where Neccesary</a>
+</dt>
+</dl>
+</dd>
+<dt>
+<a href="#sec26">Examples</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec27">Object Inspector</a>
+</dt>
+<dt>
+<a href="#sec28">Observer Design Pattern</a>
+</dt>
+<dt>
+<a href="#sec29">Real World</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec30">UCW and Arnesi</a>
+</dt>
+<dt>
+<a href="#sec31">CLSQL</a>
+</dt>
+<dt>
+<a href="#sec32">Elephant</a>
+</dt>
+</dl>
+</dd>
+</dl>
+</dd>
+<dt>
+<a href="#sec33">Sources &amp;amp; Further Reading</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec34">Sources</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec35">The Art of the Metaobject Protocol</a>
+</dt>
+<dt>
+<a href="#sec36">CLOS MOP Specification</a>
+</dt>
+<dt>
+<a href="#sec37">Metaobject Protocols: Why We Want Them and What Else They Can Do</a>
+</dt>
+<dt>
+<a href="#sec38">Why Are Black Boxes so Hard to Reuse?</a>
+</dt>
+</dl>
+</dd>
+<dt>
+<a href="#sec39">Further Reading</a>
+</dt>
+<dd>
+<dl>
+<dt>
+<a href="#sec40">A Metaobject Protocol for C++</a>
+</dt>
+<dt>
+<a href="#sec41">Open Implementations and Metaobject Protocols</a>
+</dt>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</div>
+
+
+<!-- Page published by Emacs Muse begins here --><p>In Fall of 2006 I did a small project on Metaobject Protocols for my
+CS 331 class. Here lie my notes which may perhaps be useful to
+others. I hope to expand them into something more useful over time.</p>
+
+<h2><a name="sec1" id="sec1"></a>
+Background</h2>
+
+<h3><a name="sec2" id="sec2"></a>
+Object Protocols</h3>
+
+<p class="first">An object protocol is a set of methods and specification of the
+interactions between the methods which provide some generic behavior
+(e.g. of a sequence) that are then implemented by classes which
+conform to the protocol (e.g. a vector or list). In most object
+systems a class contains both the methods which implement a protocol
+and the data used by the implementation. The intent is to emulate
+state machines which pass messages between each other.</p>
+
+
+<h3><a name="sec3" id="sec3"></a>
+CLOS Way of OO</h3>
+
+<p class="first">The Common Lisp Object System (CLOS) is different. It separates
+the data and method concepts into classes and generics. A class
+contains data fields only, and a generic has methods specialized for
+certain types attached to it. This seems a bit weird at first, but is
+significantly more powerful as it encourages complete encapsulation
+through its use of classes primarily for method specialization rather
+than for state storage.</p>
+
+
+<h4><a name="sec4" id="sec4"></a>
+Classes for scratch data and types</h4>
+
+<p class="first">In CLOS classes store data in slots (which are the same as data
+members). Encapsulation is not provided; any bit of code can use
+<code>slot-value</code> to access or set the value of a slot. This may seem odd at
+first, but encapsulation is of questionable importance as the slots
+are meant only to be used by the protocol defined around the class.</p>
+
+<p>Classes are defined with defclass</p>
+
+<pre class="src">
+(<span style="color: #00ffff;">defclass</span> <span style="color: #98fb98;">name</span> (superclasses ...)
+  ((slot-name <span style="color: #b0c4de;">:accessor</span> slot-accessor ...)
+   ...)
+  (class-options ...))
+
+(<span style="color: #00ffff;">defclass</span> <span style="color: #98fb98;">example</span> ()
+  ((foo <span style="color: #b0c4de;">:accessor</span> foo-of <span style="color: #b0c4de;">:initform</span> 5)))
+
+(<span style="color: #00ffff;">defclass</span> <span style="color: #98fb98;">example-child</span> (example)
+  ((bar <span style="color: #b0c4de;">:accessor</span> bar-of <span style="color: #b0c4de;">:initform</span> (list 1 2 3))))
+</pre>
+
+<p>Slot defintions have several option; the above example shows only the
+<code>:accessor</code> and <code>:initform</code> options which are the most commonly
+used. <code>:accessor</code> generates an accessor for the slot (e.g. if you have
+an instance of <code>example</code> you can <code>(setf (foo-of some-example-instance) 'some-value)</code> to set and <code>(foo-of some-example-instance)</code> to access the
+value). <code>:initform</code> provides a default initial value for the slot as a
+symbolic expression to be evaluated when an instance is created.</p>
+
+
+<h4><a name="sec5" id="sec5"></a>
+Generics with methods that implement protocols</h4>
+
+<p class="first">Generics are like normal functions in Lisp, but they only provide a
+lambda list (parameter list). Methods are added to the generic which
+specialize on the types of their parameters, and provide the actual
+implementation. This allows for rich layered protocols to be developed
+which can enable selective modification of individual facets with
+minimal code.</p>
+
+<pre class="src">
+(<span style="color: #00ffff;">defgeneric</span> <span style="color: #87cefa;">generic</span> (parameters ...)
+  (options) ...)
+
+(<span style="color: #00ffff;">defmethod</span> <span style="color: #87cefa;">generic-name</span> ((parameter type) parameter ...)
+  <span style="color: #b3b3b3;">"documentation string"</span>
+  body)
+
+(<span style="color: #00ffff;">defgeneric</span> <span style="color: #87cefa;">foo</span> (bar baz quux)
+  (<span style="color: #b0c4de;">:documentation</span> <span style="color: #b3b3b3;">"Process the baz with the quux capacitor to make the
+foo widget fly into the sky at warp speed"</span>))
+
+(<span style="color: #00ffff;">defmethod</span> <span style="color: #87cefa;">foo</span> ((bar example) baz (quux capacitor))
+  (launch bar (process-with quux baz)))
+</pre>
+
+<p>A method lambda list differs from a normal lambda list only in that it
+can specify the type of the parameter using the notation <code>(name type)</code>.
+Note also that methods can specialize on the types of every
+argument and not just the first one. This is quite powerful for
+reasons outside of the scope of this presentation.</p>
+
+
+
+
+<h2><a name="sec6" id="sec6"></a>
+Limitations of Default Language Behavior</h2>
+
+<p class="first">The behavior of a language is a compromise between many competing
+issues that attempts to be as generally useful as possible, and most
+applications will have no issue with the default behavior. There are,
+however, certain applications that could be cleanly written with minor
+modifications to the behavior of the language, but would be impossible
+or quite difficult to write otherwise.</p>
+
+<h3><a name="sec7" id="sec7"></a>
+Slot Storage</h3>
+
+<p class="first">Most languages choose to preallocate storage for all of the slots of
+an instance. Imagine a contact database that stored information about
+people as slots of the class. There may be dozens of slots, but often
+many of them will be left blank. If slot storage is preallocated much
+memory will be wasted and the system may not be able to fit into the
+memory of the hardware it must run on (perhaps for financial reasons,
+huge datasets, etc.).</p>
+
+<p>To save memory the author of the contact database must implement his
+own system to store properties and allocate them lazily. This
+represents a fair bit of effort, and would implement a system that
+differed from the existing slot system of classes only in the method
+of data storage.</p>
+
+<p>It would be useful if there were a way to customize instance
+allocation. The customizations would be minor and require overriding
+only the initial allocation behavior and the behavior of the first
+assignment to the slot. It is a a trivial problem in a language that
+allows customization of these.</p>
+
+
+<h3><a name="sec8" id="sec8"></a>
+Design Patterns</h3>
+
+<p class="first">Design Patterns are generalized versions of common patterns found in
+programs. Many of them are merely methods to get around deficiencies
+in the language, and can be quite messy to implement in some
+languages.</p>
+
+
+
+<h2><a name="sec9" id="sec9"></a>
+Metasoftware</h2>
+
+<p class="first">Some types of programs could be written easily if the language were
+customizable, but are nearly impossible to write when it is not.</p>
+
+<h3><a name="sec10" id="sec10"></a>
+Runtime Generated Classes</h3>
+
+<p class="first">Say you wanted to write a video game where players could create their
+own objects, attach behaviors to the objects, and perhaps mix
+different objects together to create new ones. When you abstract the
+problem this looks just like an object system!  Wouldn't it be nice if
+your program could create new objects and methods on the fly portably?</p>
+
+
+<h3><a name="sec11" id="sec11"></a>
+Object Inspection</h3>
+
+<p class="first">Imagine if you were developing a complicated program with many
+different objects that interacted in fairly complex ways. A tool to
+inspect the structure of objects while debugging would be quite
+useful, but in a traditional language would be impossible to implement
+portably. This could force you to purchase a certain compiler
+implementation which provided one, and even then would more than
+likely not be customizable.</p>
+
+<p>This problem can be generalized to apply to most debugging tools; it
+would be useful to write such tools portably because users of the
+<em>language</em> and not the <em>compiler</em> need to debug software. Sharing
+infrastructure would result in better tools (more developers), and
+save man-years of wasted effort that comes with having to rewrite
+non-portable functionality from scratch multiple times.</p>
+
+
+
+<h2><a name="sec12" id="sec12"></a>
+Metaobject Protocols</h2>
+
+<h3><a name="sec13" id="sec13"></a>
+Limited/Generalized Internals of the Implementation</h3>
+
+<p class="first">A Metaobject protocol is a generalized and limited subset of the
+underlying implementation of the language. It is generalized and
+limited in scope to allow for multiple implementation strategies;
+this, along with careful design, is essential because programming
+language research is ever advancing and new techniques for creating
+more reliable and faster implementations are still being discovered.</p>
+
+<p>This subset of the implementation is exported as a set of methods on
+metaobjects. Thus the system is implemented in itself. The system can
+then be customized using the extension and overriding features of the
+system.</p>
+
+
+<h3><a name="sec14" id="sec14"></a>
+Classes of MOPs</h3>
+
+<h4><a name="sec15" id="sec15"></a>
+Reflective</h4>
+
+<p class="first">A reflective MOP provides a functional/procedural interface to
+information about the system. It exposes class relationships, the
+methods are attached to a generic, etc. A reflective MOP often
+provides some functionality for creating new classes at runtime.</p>
+
+<h5>Example: Object Inspector</h5>
+
+
+<h5>Example: Runtime Generated Classes and Methods</h5>
+
+
+
+<h4><a name="sec16" id="sec16"></a>
+Intercessory</h4>
+
+<p class="first">Intercessory MOPs allow the user to customize language behavior by
+implementing methods which override certain aspects of the language
+behavior. This class of MOPs are what make MOPs especially
+powerful. No longer must a problem be restructured to fit the
+implementation language; the underyling language can be reshaped to
+fit the task at hand, and obfuscation of the intended structure of the
+application can be avoided.</p>
+
+<h5>Example: Lazily Allocated Slots</h5>
+
+
+<h5>Example: Observer Design Pattern</h5>
+
+
+
+
+<h3><a name="sec17" id="sec17"></a>
+Violation of Encapsulation?</h3>
+
+<p class="first">A MOP may seem like a violation of encapsulation by revealing some
+implementation details, but in reality a well designed protocol does
+not reveal anything which was not already exposed. Implementation
+decisions affect users, and some of these details do leak through to
+higher levels (e.g. the memory layout of slots). Implicit in the
+protocol specification are these implementation details, and the MOP
+merely makes this limited subset available for customization.</p>
+
+<p>A MOP makes it possible to customize certain implementation decisions
+that do not <strong>radically</strong> alter the behavior of the base language. The
+conceptual vocabulary of the system retains its meaning, and so code
+written in one dialect can interact with code written in another
+without knowing that they speak different ones.</p>
+
+
+
+<h2><a name="sec18" id="sec18"></a>
+MOP Design Principles</h2>
+
+<h3><a name="sec19" id="sec19"></a>
+Layered Protocol</h3>
+
+<p class="first">A layered protocol design is good for both meta and normal object
+protocols, and enables a combinatorial explosion of customizations to
+the protocol.</p>
+
+<h4><a name="sec20" id="sec20"></a>
+Top level <strong>must</strong> call lower level functions</h4>
+
+<p class="first">The top level methods of a layered metaobject protocol are required to
+call certain methods to perform some tasks. This both makes it easier
+to customize the top level methods (which perform very broad tasks) by
+providing some pieces of them for the programmer, and allows more
+customization to be done by opening up the replacement of lower level
+functions as a way to alter a small detail of the high level behavior.</p>
+
+
+<h4><a name="sec21" id="sec21"></a>
+Lower level methods are easier to customize</h4>
+
+<p class="first">The lower level methods of a MOP are limited in scope and can be
+implemented easily. Often the changes to language behavior that are
+wanted are very small, and having methods that perform simple tasks
+which are often customized reduces the effort required to extend the
+system.</p>
+
+
+
+<h3><a name="sec22" id="sec22"></a>
+Functional Where Possible</h3>
+
+<p class="first">Functional protocols are preferred for MOPs (and object protocol in
+general). Functional protocols open up several optimizations for the
+implementation without burdening the user of the protocol.</p>
+
+<h4><a name="sec23" id="sec23"></a>
+Memoization</h4>
+
+<p class="first">Memoization is the process of saving the results of a function call
+for future use. This avoids expensive recomputation of values which
+have not changed (recall that a true function will always return the
+same result when given the same arguments).</p>
+
+<p>A functional MOP can be optimized easily by exploiting this property
+to memoize the return values of calls to expensive operations. A MOP
+must be be very fast to avoid making programs unusably slow, and
+memoization is able to give an appreciable speedup in many cases
+without an insignificant burden on memory usage.</p>
+
+<h5>Constant Shared Return Values</h5>
+
+<p>Disallowing the modification of values returned by protocol methods
+allows the implementation to return large data structures by reference
+to avoid expensive copying without having to do expensive data
+integrity checks.</p>
+
+
+
+<h4><a name="sec24" id="sec24"></a>
+Cleaner Code</h4>
+
+
+
+<h3><a name="sec25" id="sec25"></a>
+Procedural Only Where Neccesary</h3>
+
+<p class="first">Some operations like method invocation are inheretly stateful and so
+must use a procedural protocol. There is no benefit to be gained from
+using a functional protocol, and indeed an attempt would result in
+obtuse code that severely restricted the implementor. Do note that
+only a very small part of method invocation is stateful (the actual
+call), and most of it can be implemented functionally (e.g. computing
+the discriminating function).</p>
+
+
+
+<h2><a name="sec26" id="sec26"></a>
+Examples</h2>
+
+<h3><a name="sec27" id="sec27"></a>
+Object Inspector</h3>
+
+<p class="first">A primitive portable object inspector is presented here.</p>
+
+<pre class="src">
+(<span style="color: #00ffff;">defgeneric</span> <span style="color: #87cefa;">example-inspect</span> (instance)
+  (<span style="color: #b0c4de;">:documentation</span> <span style="color: #b3b3b3;">"Simple object inspector using CLOS MOP"</span>))
+
+(<span style="color: #00ffff;">defmethod</span> <span style="color: #87cefa;">example-inspect</span> ((instance t))
+  (format t <span style="color: #b3b3b3;">"Simple Object~% Value: ~S~%"</span> instance))
+
+(<span style="color: #00ffff;">defmethod</span> <span style="color: #87cefa;">example-inspect</span> ((instance standard-object))
+  (<span style="color: #00ffff;">let</span> ((class (class-of instance)))
+    (format t <span style="color: #b3b3b3;">"Class: ~S, Superclasses: ~S~%"</span>
+            (class-name class)
+            (mapcar #'class-name
+                    (class-precedence-list class)))
+    (<span style="color: #00ffff;">let</span> ((slot-names (mapcar #'slot-definition-name
+                              (class-slots class))))
+      (format t <span style="color: #b3b3b3;">"Slots: ~%~{ ~S~%~}"</span> slot-names)
+      (inspect-loop slot-names instance #'example-inspect))))
+
+(<span style="color: #00ffff;">defun</span> <span style="color: #87cefa;">inspect-loop</span> (slots instance inspector)
+  (format t <span style="color: #b3b3b3;">"Enter slot to inspect or :pop to go up one level: "</span>)
+  (finish-output)
+  (<span style="color: #00ffff;">let*</span> ((slot (read))
+         (found-slot (member slot slots)))
+    (<span style="color: #00ffff;">cond</span> (found-slot
+           (funcall inspector (slot-value instance slot))
+           (funcall inspector instance))
+          ((eq slot <span style="color: #b0c4de;">:pop</span>) t)
+          (t
+           (format t <span style="color: #b3b3b3;">"~S is invalid. Valid slot names: ~S~%"</span>
+                   slot
+                   slots)
+           (inspect-loop slots instance inspector)))))
+</pre>
+
+
+<h3><a name="sec28" id="sec28"></a>
+Observer Design Pattern</h3>
+
+<p class="first">A simple implementation of the observer pattern is under 100 lines,
+and the user level code requires only a single line of code to make
+any existing class observable.</p>
+
+<p>In a language lacking a MOP, implementing the observer pattern
+requires modifying every accessor of a class to explicitly invoke any
+observers, and neccesitates the addition of a mixin class to the class
+heirarchy. The fact that an object can be observed is a meta property
+of the class, and forcing it to be implemented at the application
+level dirties the inheritance heirarchy and adds uneccesary meta
+details to the program.</p>
+
+<pre class="src">
+<span style="color: #ff7f24;">;;; </span><span style="color: #ff7f24;">This metaclass adds a slot to instances which use it, and so the
+</span><span style="color: #ff7f24;">;;; </span><span style="color: #ff7f24;">system is defined in its own package to avoid name conflicts
+</span>(<span style="color: #00ffff;">defpackage</span> <span style="color: #98fb98;">:observer</span>
+  (<span style="color: #b0c4de;">:use</span> <span style="color: #b0c4de;">:cl</span> #+sbcl <span style="color: #b0c4de;">:sb-mop</span>)
+  (<span style="color: #b0c4de;">:export</span> observable register-observer unregister-observer))
+
+(<span style="color: #00ffff;">in-package</span> <span style="color: #b0c4de;">:observer</span>)
+
+<span style="color: #ff7f24;">;;; </span><span style="color: #ff7f24;">Metaclass
+</span>(<span style="color: #00ffff;">defclass</span> <span style="color: #98fb98;">observable</span> (standard-class)
+  ()
+  (<span style="color: #b0c4de;">:documentation</span> <span style="color: #b3b3b3;">"Metaclass for observable objects"</span>))
+
+(<span style="color: #00ffff;">defmethod</span> <span style="color: #87cefa;">compute-slots</span> ((class observable))
+  <span style="color: #b3b3b3;">"Add a slot for storing observers to observable instances"</span>
+  (cons (make-instance 'standard-effective-slot-definition
+                       <span style="color: #b0c4de;">:name</span> 'observers
+                       <span style="color: #b0c4de;">:initform</span> '(make-hash-table)
+                       <span style="color: #b0c4de;">:initfunction</span> #'(<span style="color: #00ffff;">lambda</span> () (make-hash-table)))
+        (call-next-method)))
+
+(<span style="color: #00ffff;">defmethod</span> <span style="color: #87cefa;">validate-superclass</span> ((class observable)
+                                (super standard-class))
+  t)
+
+(<span style="color: #00ffff;">defun</span> <span style="color: #87cefa;">register-observer</span> (instance slot-name key closure)
+  (register-observer-with-class (class-of instance)
+                                instance
+                                slot-name
+                                key
+                                closure))
+
+(<span style="color: #00ffff;">defun</span> <span style="color: #87cefa;">unregister-observer</span> (instance slot-name key)
+  (unregister-observer-with-class (class-of instance)
+                                  instance
+                                  slot-name
+                                  key))
+
+(<span style="color: #00ffff;">defun</span> <span style="color: #87cefa;">get-observers</span> (instance slot-name)
+  (get-observers-with-class (class-of instance)
+                            instance
+                            slot-name))
+
+(<span style="color: #00ffff;">defun</span> <span style="color: #87cefa;">add-observer-table</span> (instance slot-name)
+  (setf (gethash slot-name (slot-value instance
+                                       'observers))
+        (make-hash-table)))
+
+(<span style="color: #00ffff;">defgeneric</span> <span style="color: #87cefa;">register-observer-with-class</span> (class instance slot-name key closure))
+(<span style="color: #00ffff;">defgeneric</span> <span style="color: #87cefa;">unregister-observer-with-class</span> (class
+                                            instance
+                                            slot-name
+                                            key))
+
+(<span style="color: #00ffff;">defmethod</span> <span style="color: #87cefa;">register-observer-with-class</span> ((class observable)
+                                         instance
+                                         slot-name
+                                         key
+                                         closure)
+  (setf (gethash key
+                 (or (gethash slot-name
+                              (slot-value instance 'observers))
+                     <span style="color: #ff7f24;">;; </span><span style="color: #ff7f24;">Lazily add observer hash tables
+</span>                     (add-observer-table instance slot-name)))
+        closure))
+
+(<span style="color: #00ffff;">defmethod</span> <span style="color: #87cefa;">unregister-observer-with-class</span> ((class observable)
+                                           instance
+                                           slot-name
+                                           key)
+  (remhash key (gethash slot-name
+                        (slot-value instance 'observers))))
+
+(<span style="color: #00ffff;">defmethod</span> <span style="color: #87cefa;">get-observers-with-class</span> ((class observable)
+                                     instance
+                                     slot-name)
+  (gethash slot-name (slot-value instance 'observers)))
+
+(<span style="color: #00ffff;">defmethod</span> (<span style="color: #87cefa;">setf slot-value-using-class)</span> <span style="color: #b0c4de;">:before</span> (new-value
+                                                  (class observable)
+                                                  instance
+                                                  slot)
+  (<span style="color: #00ffff;">let</span> ((slot-name (slot-definition-name slot)))
+    (<span style="color: #00ffff;">if</span> (not (eq 'observers slot-name))
+        (<span style="color: #00ffff;">let</span> ((observers
+               (get-observers instance (slot-definition-name slot))))
+          (<span style="color: #00ffff;">if</span> observers
+              (maphash #'(<span style="color: #00ffff;">lambda</span> (key observer)
+                           (funcall observer
+                                    (<span style="color: #00ffff;">if</span> (slot-boundp instance slot-name)
+                                        (slot-value instance slot-name)
+                                      nil)
+                                    new-value))
+                       observers))))))
+</pre>
+
+
+<h3><a name="sec29" id="sec29"></a>
+Real World</h3>
+
+<h4><a name="sec30" id="sec30"></a>
+<a href="http://common-lisp.net/project/ucw/">UCW</a> and <a href="http://common-lisp.net/project/bese/arnesi.html">Arnesi</a></h4>
+
+<p class="first">Arnesi uses the CLOS MOP to implement methods which are transparantly
+rewritten into continuation passing style. This allows their execution
+to be suspended at certain points and resumed later. UCW builds on top
+of this to support a web framework where the statelessness of http is
+hidden from the user; displaying a page suspends the execution of the
+current continuation, and resumes it upon submission. The user level
+code is completely unaware of this.</p>
+
+
+<h4><a name="sec31" id="sec31"></a>
+<a href="http://clsql.b9.com">CLSQL</a></h4>
+
+<p class="first">CLSQL uses the reflective part of the CLOS MOP to map Common Lisp data
+types into SQL types, and the intercessory protocol for slot
+allocation to map slots onto database columns or sql expressions (for
+implementing relational slots).</p>
+
+
+<h4><a name="sec32" id="sec32"></a>
+<a href="http://common-lisp.net/project/elephant/">Elephant</a></h4>
+
+<p class="first">Elephant uses the CLOS MOP to transparantly store any class to disk
+and handle paging between the disk store and memory efficiently and
+with no user intervention.</p>
+
+
+
+
+<h2><a name="sec33" id="sec33"></a>
+Sources &amp;amp; Further Reading</h2>
+
+<h3><a name="sec34" id="sec34"></a>
+Sources</h3>
+
+<h4><a name="sec35" id="sec35"></a>
+The Art of the Metaobject Protocol</h4>
+
+<h5>Kiczales, Gregor et al. MIT Press 1991</h5>
+
+<p>Highly recommended reading even if you plan to never implement a MOP
+or use the CLOS one. The design principles it recommends are quite
+useful.</p>
+
+
+
+<h4><a name="sec36" id="sec36"></a>
+<a href="http://www.lisp.org/mop/contents.html">CLOS MOP Specification</a></h4>
+
+<p class="first">Specification of the MOP for CLOS defined in <em>The Art of the Metaobject Protocol</em>.</p>
+
+
+<h4><a name="sec37" id="sec37"></a>
+<a href="http://citeseer.ist.psu.edu/399658.html">Metaobject Protocols: Why We Want Them and What Else They Can Do</a></h4>
+
+<p class="first">A short overview of MOP design principles followed by three example
+metaobject protocols for Scheme.</p>
+
+
+<h4><a name="sec38" id="sec38"></a>
+<a href="http://www2.parc.com/csl/groups/sda/projects/oi/towards-talk/transcript.html">Why Are Black Boxes so Hard to Reuse?</a></h4>
+
+<p class="first">Transcription of a talk on the benefits of open implementations of
+software. It first discusses several problems that black box software
+implementations pose, and then presents existing solutions. It shows
+how the existing solutions are insufficient, and then provides
+metaobject protocols as a solution to most of the problems.</p>
+
+
+
+<h3><a name="sec39" id="sec39"></a>
+Further Reading</h3>
+
+<h4><a name="sec40" id="sec40"></a>
+<a href="http://citeseer.ist.psu.edu/chiba95metaobject.html">A Metaobject Protocol for C++</a></h4>
+
+<p class="first">Example of a purely compile time MOP. It implements the functionality
+of a code walker and something similar to the Lisp macro system.</p>
+
+
+<h4><a name="sec41" id="sec41"></a>
+<a href="http://www.parc.com/csl/groups/sda/publications/papers/Kiczales-TUT95/for-web.pdf">Open Implementations and Metaobject Protocols</a></h4>
+
+<p class="first">It is a bit long, but it seems to follow a similar structure to AMOP
+in introducing MOPs and their usefulness. The pages are slides with
+notes, and so the 331 pages might not actually take that long to read.</p>
+
+
+
+
+  <!-- Page published by Emacs Muse ends here -->
+
+  <p class="cke-buttons">
+    <!-- validating badges, any browser, etc -->
+    <a href="http://validator.w3.org/check/referer"><img
+       src="http://www.w3.org/Icons/valid-xhtml10"
+       alt="Valid XHTML 1.0!" /></a>
+    
+    <a href="http://www.anybrowser.org/campaign/"><img
+       src="img/buttons/w3c_ab.png" alt="[ Viewable With Any Browser
+       ]" /></a>
+
+    <a href="http://www.debian.org/"><img
+       src="img/buttons/debian.png" alt="[ Powered by Debian ]" /></a>
+    
+    <a href="http://hcoop.net/">
+      <img src="img/buttons/hcoop.png" 
+       alt="[ Hosted by HCoop]" />
+    </a>
+
+    <a href="http://www.fsf.org/register_form?referrer=114">
+      <img src="img/buttons/fsf_member.png"
+       alt="[ FSF Associate Member ]" />
+    </a>
+  </p>
+
+<p class="cke-footer">                         Ruled by the ebb of my oceans                         
+                        Slaves to the dusk and the dawn                        
+                         Your petri dish civilisations                        
+                             Are buried and born                              
+</p>
+<p class="cke-timestamp">Last Modified:
+    March 13, 2008</p>
+  </body>
+</html>
\ No newline at end of file